package com.brillilab.service.core.kit.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.brillilab.common.entity.PageVo;
import com.brillilab.common.utils.DateUtil;
import com.brillilab.dao.mapper.kit.KitUsageMapper;
import com.brillilab.domain.enums.kit.KitEnum;
import com.brillilab.domain.enums.kit.KitUsageEnum;
import com.brillilab.domain.po.kit.KitUsage;
import com.brillilab.domain.vo.home.HomeChartVo;
import com.brillilab.domain.vo.home.HomeMaterielVo;
import com.brillilab.domain.vo.kit.DeviceUnlock;
import com.brillilab.domain.vo.kit.KitUsageVo;
import com.brillilab.service.core.kit.IKitUsageService;
import com.brillilab.service.core.kit.IReagentTypeService;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 取用/待归还清单
 *
 * @author wmh
 */
@Service
@Transactional
public class KitUsageServiceImpl implements IKitUsageService {

    @Resource
    private KitUsageMapper kitUsageMapper;
    @Resource
    private IReagentTypeService reagentTypeService;

    @SuppressWarnings("unchecked")
    @Override
    public List<KitUsage> selectList(Long labId,Long labMemberId,Integer... state) {

        return kitUsageMapper.selectExistList(labId,labMemberId,state);
    }

    @Override
    public boolean insert(KitUsage kitUsage) {
        return kitUsageMapper.insert(kitUsage) == 1;
    }

    @Override
    public KitUsage selectOne(Long id) {
        return kitUsageMapper.selectById(id);
    }

    @Override
    public KitUsage selectOne(Long usageId,Long labId,Long labMemberId,Integer state) {
        return kitUsageMapper.selectOne(
                new LambdaQueryWrapper<KitUsage>()
                        .eq(KitUsage::getId,usageId)
                        .eq(KitUsage::getLabId,labId)
                        .eq(KitUsage::getLabMemberId,labMemberId)
                        .eq(KitUsage::getState,state)
        );
    }

    @Override
    public boolean deleteById(Long id) {
        return kitUsageMapper.deleteById(id) == 1;
    }

    @Override
    public boolean deleteBatch(List<Long> itemIds) {
        if(itemIds.size()>0){
            return kitUsageMapper.deleteBatchIds(itemIds) >= 0;
        }
        return true;
    }

    @Override
    public boolean update(KitUsage kitUsage) {
        return kitUsageMapper.updateById(kitUsage) == 1;
    }

    @Override
    public Integer saveTakeList(List<KitUsage> list) {
        return kitUsageMapper.saveTakeList(list);
    }

    @Override
    public List<KitUsage> getUsageChartByDateRange(Long labId,Long labMemberId, Date beginDate, Date endDate) {

        LambdaQueryWrapper<KitUsage> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(KitUsage::getLabId, labId);
        queryWrapper.eq(KitUsage::getLabMemberId, labMemberId);
        queryWrapper.ge(KitUsage::getUsageTime, beginDate);
        queryWrapper.le(KitUsage::getUsageTime, endDate);
        queryWrapper.ne(KitUsage::getState,KitUsageEnum.State.TAKE.getValue());//过滤未取用的记录
        return kitUsageMapper.selectList(queryWrapper);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<KitUsage> selectList(Long labId,Long labMemberId,Date usageTime,Integer... states) {
        return kitUsageMapper.selectList(
                new LambdaQueryWrapper<KitUsage>()
                        .eq(KitUsage::getLabId,labId)
                        .eq(KitUsage::getLabMemberId,labMemberId)
                        .eq(KitUsage::getUsageTime,usageTime)
                        .in(KitUsage::getState, (Object) states)
                        .orderByDesc(KitUsage::getUsageTime));
    }

    @Override
    public Integer insertBatch(List<KitUsage> kitUsages) {
        Integer count = 0;
        if(!CollectionUtils.isEmpty(kitUsages)){
            for (KitUsage kitUsage:kitUsages){
                int insert=kitUsageMapper.insert(kitUsage);
                count+=insert;
            }
        }
        return count;
    }

    @Override
    public Integer updateBatch(List<KitUsage> updateList) {
        if(updateList.size()>0){
            return kitUsageMapper.updateBatch(updateList);
        }
        return 0;
    }

    @Override
    public int selectCount(Long labId,Long labMemberId,Integer... state) {
        return kitUsageMapper.selectKitUsageCount(false,labId,labMemberId,null,state);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<KitUsage> selectList(Long inventoryId,Integer state) {
        return kitUsageMapper.selectList(new LambdaQueryWrapper<KitUsage>()
                .eq(KitUsage::getInventoryId,inventoryId)
                .eq(KitUsage::getState,state)
                .orderByDesc(KitUsage::getUpdateTime));
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<KitUsage> selectByKitId(Long kitId,Integer state) {
        return kitUsageMapper.selectList(new LambdaQueryWrapper<KitUsage>()
                .eq(KitUsage::getKitId,kitId)
                .eq(KitUsage::getState,state)
                .orderByDesc(KitUsage::getUpdateTime));
    }

    @Override
    public List<KitUsageVo> getKitUsageVoList(Long labId,Long labMemberId,Integer... states) {
        return kitUsageMapper.selectKitUsageVoList(labId,labMemberId,states).stream().peek(e ->{
            if(KitEnum.Classify.SAMPLE.getValue().equals(e.getClassify())){
                e.setKitType(2);
            }
            //使用人名称
            String userName = kitUsageMapper.selectKitUserName(e.getInventoryId());
            if(e.getIsUse().equals(1)){
                e.setUserName(userName);
            }
        }).collect(Collectors.toList());
    }

    @Override
    public List<KitUsageVo> getKitUsageVoList(List<Long> usageIds,Integer... states) {
        if(usageIds.size()>0){
            return kitUsageMapper.getKitUsageVoList(usageIds,states).stream().peek(e ->{
                if(KitEnum.Classify.SAMPLE.getValue().equals(e.getClassify())){
                    e.setKitType(2);
                }
                //使用人名称
                String userName = kitUsageMapper.selectKitUserName(e.getInventoryId());
                if(e.getIsUse().equals(1)){
                    e.setUserName(userName);
                }
            }).collect(Collectors.toList());
        }
        return new ArrayList<>(0);
    }

    @Override
    public List<KitUsage> selectList(List<Long> kitUsageIds) {
        if(kitUsageIds.size()>0){
            return kitUsageMapper.selectList(new LambdaQueryWrapper<KitUsage>()
                    .in(KitUsage::getId,kitUsageIds));
        }
        return new ArrayList<>(0);
    }

    @Override
    public List<KitUsage> selectListInOneDevice(Long deviceId,Long labId,Long labMemberId,Integer state) {
        return kitUsageMapper.selectListInOneDevice(deviceId,labId,labMemberId,state);
    }

    @Override
    public DeviceUnlock selectKitUsageDeviceUnLock(Long usageId) {
        return kitUsageMapper.selectKitUsageDeviceUnlock(usageId);
    }

    @Override
    public List<DeviceUnlock> selectKitUsageDeviceUnLockList(List<Long> kitUsageIds) {
        if(kitUsageIds.size()>0){
            return kitUsageMapper.selectKitUsageDeviceUnLockList(kitUsageIds);
        }
        return new ArrayList<>(0);
    }

    @Override
    public List<KitUsage> selectListByExperimentId(Long experimentId) {
        return kitUsageMapper.selectList(new LambdaQueryWrapper<KitUsage>()
                .eq(KitUsage::getExperimentId,experimentId)
                .in(KitUsage::getState,KitUsageEnum.State.TAKE.getValue(),KitUsageEnum.State.NOT_RETURN.getValue(),KitUsageEnum.State.RETURNED.getValue()));
    }

    @Override
    public KitUsageVo getKitUsageVo(Long id) {
        return kitUsageMapper.selectKitUsageVo(id);
    }

    @Override
    public int selectExperimentUsageCount(Long labId,Long labMemberId,Long experimentId,Integer... states) {
        return kitUsageMapper.selectKitUsageCount(true,labId,labMemberId,experimentId,states);
    }

    @Override
    public boolean setUsageToTakeMiss(List<Long> notReturnIds) {
        if(notReturnIds.size()>0){
            return kitUsageMapper.setUsageToTakeMiss(notReturnIds) >= 0;
        }
        return true;
    }

    @Override
    public boolean setUsageToReturnMiss(List<Long> returnedIds) {
        if(returnedIds.size()>0){
            return kitUsageMapper.setUsageToReturnMiss(returnedIds) >= 0;
        }
        return true;
    }

    @Override
    public PageVo<KitUsageVo> getNotRetureUsageList(Long labMemberId,Integer state,Integer pageNum,Integer pageSize) {
        pageNum = pageNum <=0 ? 1 : pageNum;
        pageSize = pageSize <=0 ? 10 : pageSize;
        PageHelper.startPage(pageNum,pageSize);
        List<KitUsageVo> kitUsages = kitUsageMapper.selectKitUsageListByState(labMemberId,state);
        Integer count = kitUsageMapper.selectKitUsageCountByState(labMemberId,state);
        return getLastPageResult(pageNum,pageSize,count,kitUsages);
    }
    @Override
    public PageVo<KitUsageVo> getHistoryKitUsageVoPage(Long labId,Long labMemberId,Integer pageNum,Integer pageSize) {
        pageNum = pageNum <=0 ? 1 : pageNum;
        pageSize = pageSize <=0 ? 10 : pageSize;
        PageHelper.startPage(pageNum,pageSize);
        List<KitUsageVo> kitUsages=kitUsageMapper.selectHistoryKitUsageVoList(labId,labMemberId).stream().peek(e ->{
            if(KitEnum.Classify.SAMPLE.getValue().equals(e.getClassify())){
                e.setKitType(2);
            }
            //使用人名称
            String userName = kitUsageMapper.selectKitUserName(e.getInventoryId());
            if(e.getIsUse().equals(1)){
                e.setUserName(userName);
            }
        }).collect(Collectors.toList());

        Integer count=kitUsageMapper.selectHistoryCount(labId,labMemberId);

        return getLastPageResult(pageNum,pageSize,count,kitUsages);
    }

    @Override
    public boolean setUsageToNotTakeSuccess(List<Long> returnedIds) {
        if(returnedIds.size()>0){
            return kitUsageMapper.setUsageToNotTakeSuccess(returnedIds) >= 0;
        }
        return true;
    }

    @Override
    public boolean setUsageToNotReturnSuccess(List<Long> returnedIds) {
        if(returnedIds.size()>0){
            return kitUsageMapper.setUsageToNotReturnSuccess(returnedIds) > 0;
        }
        return true;
    }

    @Override
    public List<KitUsage> selectListInInventoryIds(List<Long> inventoryIds,Integer... states) {
        if(inventoryIds.size()>0 && states.length>0){
            return kitUsageMapper.selectList(
                    new LambdaQueryWrapper<KitUsage>()
                            .in(KitUsage::getInventoryId,inventoryIds)
                            .in(KitUsage::getState,Arrays.asList(states)));
        }
        return new ArrayList<>(0);
    }

    @Override
    public PageVo<KitUsageVo> getKitUsageVoPage(Long labId,Long labMemberId,Integer pageNum,Integer pageSize,Integer... states) {
        pageNum = pageNum <=0 ? 1 : pageNum;
        pageSize = pageSize <=0 ? 10 : pageSize;
        PageHelper.startPage(pageNum,pageSize);
        List<KitUsageVo> kitUsages=kitUsageMapper.selectKitUsageVoList(labId,labMemberId,states).stream().peek(e ->{
            if(KitEnum.Classify.SAMPLE.getValue().equals(e.getClassify())){
                e.setKitType(2);
            }
            //使用人名称
            String userName = kitUsageMapper.selectKitUserName(e.getInventoryId());
            if(e.getIsUse().equals(1)){
                e.setUserName(userName);
            }
        }).collect(Collectors.toList());

        Integer exp=kitUsageMapper.selectKitUsageCount(true,labId,labMemberId,null,states);
        Integer noExp=kitUsageMapper.selectKitUsageCount(false,labId,labMemberId,null,states);

        return getLastPageResult(pageNum,pageSize,exp+noExp,kitUsages);
    }

    private PageVo<KitUsageVo> getLastPageResult(Integer pageNum,Integer pageSize,Integer totalRow,List<KitUsageVo> content) {
        PageVo<KitUsageVo> page=new PageVo<>();
        int startRow=pageSize * (pageNum - 1);
        int totalPage=totalRow % pageSize > 0 ? totalRow / pageSize  + 1 : totalRow / pageSize;
        page.setContent(content);
        page.setHasPrevious(pageNum>1);
        page.setHasNext(pageNum < totalPage);
        page.setPageNum(pageNum);
        page.setPageSize(pageSize);
        page.setTotalRow(totalRow);
        page.setTotalPage(totalPage);
        page.setStartRow(startRow +1);
        return page;
    }

	@Override
	public List<HomeChartVo> getSevenDaysUsageChart(Long labMemberId) {
		List<HomeChartVo> chartList = kitUsageMapper.getSevenDaysUsageChart(labMemberId);
		if(chartList.size()<7) {
			Map<String, List<HomeChartVo>> map = chartList.stream().collect(Collectors.groupingBy(HomeChartVo::getDate));
			List<String> sevenDay = DateUtil.getBeforeSevenDay("MM-dd");
			for (String day : sevenDay) {
				List<HomeChartVo> list = map.get(day);
				if(CollectionUtils.isEmpty(list)) {
					HomeChartVo vo = new HomeChartVo();
					vo.setDate(day);
					chartList.add(vo);
				}
			}
		}
		return chartList;
	}

	@Override
	@SuppressWarnings("unchecked")
	public HomeMaterielVo getMaterielVo(Long labMemberId) {
		HomeMaterielVo  materielVo = new HomeMaterielVo();
		LambdaQueryWrapper<KitUsage> wrapper = new LambdaQueryWrapper<KitUsage>();
		wrapper.eq(KitUsage::getLabMemberId,labMemberId);
		wrapper.eq(KitUsage::getState,KitUsageEnum.State.NOT_RETURN.getValue());
		wrapper.orderByDesc(KitUsage::getUsageTime);
		Page<KitUsage> page=new Page<>(1,5);
		IPage<KitUsage> iPage = kitUsageMapper.selectPage(page, wrapper);
		List<String> reagentList = new ArrayList<String>();
		if(!CollectionUtils.isEmpty(iPage.getRecords())) {
			reagentList = iPage.getRecords().stream().map(KitUsage::getReagentName).collect(Collectors.toList());
		}
		materielVo.setTotal(iPage.getTotal());
		materielVo.setReagentList(reagentList);
		return materielVo;
	}

    @Override
    public int deleteByStepId(Long stepId) {
        return kitUsageMapper.delete(new LambdaQueryWrapper<KitUsage>().eq(KitUsage::getExperimentStepId,stepId));
    }

	@Override
	public int selectWaitGiveBackCount(Long experimentId) {
		 return kitUsageMapper.selectCount(new LambdaQueryWrapper<KitUsage>()
	                .eq(KitUsage::getExperimentId,experimentId)
	                .in(KitUsage::getState,KitUsageEnum.State.NOT_RETURN.getValue(),KitUsageEnum.State.RETURNING.getValue()));
	}
}
